
  function _instanceof(left, right) {
    if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
      return right[Symbol.hasInstance](left);
    } else {
      return left instanceof right;
    }
  }

  function _classCallCheck(instance, Constructor) {
    if (!_instanceof(instance, Constructor)) {
      throw new TypeError("Cannot call a class as a function");
    }
  }

  function _defineProperties(target, props) {
    for (var i = 0; i < props.length; i++) {
      var descriptor = props[i];
      descriptor.enumerable = descriptor.enumerable || false;
      descriptor.configurable = true;
      if ("value" in descriptor) descriptor.writable = true;
      Object.defineProperty(target, descriptor.key, descriptor);
    }
  }

  function _createClass(Constructor, protoProps, staticProps) {
    if (protoProps) _defineProperties(Constructor.prototype, protoProps);
    if (staticProps) _defineProperties(Constructor, staticProps);
    return Constructor;
  }

  var sliderRuler = (function() {
    var sliderRuler = function() {
      var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};

      _classCallCheck(this, sliderRuler);

      this.value = '';
      this.options = {
        canvasWidth: document.body.clientWidth || 375,
        canvasHeight: 83,
        boxColor: '#E4E4E4',
        scrollLeft: 0,
        heightDecimal: 35,
        heightDigit: 18,
        lineWidth: 2,
        colorDecimal: '#E4E4E4',
        colorDigit: '#E4E4E4',
        divide: 10,
        precision: 1,
        fontSize: 20,
        fontColor: '#666',
        maxValue: 230,
        minValue: 100,
        currentValue: 160
      };
      this.localState = {
        startX: 0,
        startY: 0,
        isTouchEnd: true,
        touchPoints: []
      };
      this.browserEnv = window.hasOwnProperty('ontouchstart');
      Object.assign(this.options, options);
      this.init(options);
    }

    _createClass(sliderRuler, [{
      key: "_renderBox",
      value: function _renderBox(container) {
        var box = document.createElement('div'),
        canvas = document.createElement('canvas');
        this.canvas = canvas;
        box.className = 'rulerbox';
        box.appendChild(canvas);
        container.appendChild(box);

        this._renderCanvas();
      }
    },
    {
      key: "_renderCanvas",
      value: function _renderCanvas() {
        var _this$options = this.options,
        canvasWidth = _this$options.canvasWidth,
        canvasHeight = _this$options.canvasHeight,
        canvas = this.canvas;
        canvas.width = canvasWidth * 2;
        canvas.height = canvasHeight * 2;
        canvas.style.width = canvasWidth + 'px';
        canvas.style.height = canvasHeight + 'px';
        canvas.className = 'rulerCanvas';

        if (this.browserEnv) {
          canvas.ontouchstart = this.touchStart.bind(this);
          canvas.ontouchmove = this.touchMove.bind(this);
          canvas.ontouchend = this.touchEnd.bind(this);
        } else {
          canvas.onmousedown = this.touchStart.bind(this);
          canvas.onmousemove = this.touchMove.bind(this);
          canvas.onmouseup = this.touchEnd.bind(this);
        }

        this.dreawCanvas();
      }
    },
    {
      key: "touchStart",
      value: function touchStart(e) {
        e.preventDefault();

        if (e || this.localState.isTouchEnd) {
          this.touchPoints(e);
          var touch = e.touches && e.touches[0] || e;
          this.localState.startX = touch.pageX;
          this.localState.startY = touch.pageY;
          this.localState.startT = new Date().getTime(); // 记录手指按下的开始时间
          this.localState.isTouchEnd = false; // 当前开始滑动
        }
      }
    },
    {
      key: "touchMove",
      value: function touchMove(e) {
        if (!this.browserEnv && (e.which !== 1 || e.buttons === 0)) return; // pc canvas超出边界处理
        this.touchPoints(e);
        var touch = e.touches && e.touches[0] || e,
        deltaX = touch.pageX - this.localState.startX,
        deltaY = touch.pageY - this.localState.startY; // 如果X方向上的位移大于Y方向，则认为是左右滑动
        if (Math.abs(deltaX) > Math.abs(deltaY) && Math.abs(Math.round(deltaX / this.options.divide)) > 0) {
          if (this.browserEnv && !this.rebound(deltaX)) {
            return;
          }

          this.moveDreaw(deltaX);
          this.localState.startX = touch.pageX;
          this.localState.startY = touch.pageY;
        }
      }
    },
    {
      key: "touchEnd",
      value: function touchEnd() {
        this.moveDreaw(this.browserEnv ? this.inertialShift() : 0);
        this.localState.isTouchEnd = true;
        this.localState.touchPoints = [];
        this.canvas.style.transform = 'translate3d(0, 0, 0)';
      }
    },
    {
      key: "touchPoints",
      value: function touchPoints(e) {
        var touch = e.touches && e.touches[0] || e,
        time = new Date().getTime(),
        shift = touch.pageX;
        this.localState.touchPoints.push({
          time: time,
          shift: shift
        });
      }
    },
    {
      key: "inertialShift",
      value: function inertialShift() {
        var s = 0;

        if (this.localState.touchPoints.length >= 4) {
          var _points = this.localState.touchPoints.slice( - 4),
          v = (_points[3].shift - _points[0].shift) / (_points[3].time - _points[0].time) * 1000; // v 手指离开屏幕后的速度px/s

          var a = 6000; // a 手指离开屏幕后的加速度
          s = Math.sign(v) * Math.pow(v, 2) / (2 * a); // s 手指离开屏幕后惯性距离
        }

        return s;
      }
    },
    {
      key: "rebound",
      value: function rebound(deltaX) {
        var _this$options2 = this.options,
        currentValue = _this$options2.currentValue,
        maxValue = _this$options2.maxValue,
        minValue = _this$options2.minValue;

        if (currentValue === minValue && deltaX > 0 || currentValue === maxValue && deltaX < 0) {
          var reboundX = Math.sign(deltaX) * 1.5988 * Math.pow(Math.abs(deltaX), 0.7962);
          this.canvas.style.transform = "translate3d(".concat(reboundX, "px, 0, 0)");
          return false;
        }

        return true;
      }
    },
    {
      key: "moveDreaw",
      value: function moveDreaw(shift) {
        var _this = this;

        var _this$options3 = this.options,
        divide = _this$options3.divide,
        precision = _this$options3.precision;

        var moveValue = Math.round( - shift / divide),
        _moveValue = Math.abs(moveValue),
        draw = function draw() {
          if (_moveValue < 1) {
            return;
          }

          _this.options.currentValue += Math.sign(moveValue) * precision;

          _this.dreawCanvas();

          window.requestAnimationFrame(draw);
          _moveValue--;
        };

        draw();
      }
    },
    {
      key: "dreawCanvas",
      value: function dreawCanvas() {
        var canvas = this.canvas,
        context = canvas.getContext('2d');
        canvas.height = canvas.height;
        var _this$options4 = this.options,
        canvasWidth = _this$options4.canvasWidth,
        canvasHeight = _this$options4.canvasHeight,
        maxValue = _this$options4.maxValue,
        minValue = _this$options4.minValue,
        currentValue = _this$options4.currentValue,
        handleValue = _this$options4.handleValue,
        precision = _this$options4.precision,
        divide = _this$options4.divide,
        heightDecimal = _this$options4.heightDecimal,
        heightDigit = _this$options4.heightDigit,
        lineWidth = _this$options4.lineWidth,
        colorDecimal = _this$options4.colorDecimal,
        colorDigit = _this$options4.colorDigit,
        fontSize = _this$options4.fontSize,
        fontColor = _this$options4.fontColor; // 计算当前值
        currentValue = currentValue > minValue ? currentValue < maxValue ? currentValue: maxValue: minValue;
        currentValue = Math.round(currentValue * 10 / precision) * precision / 10;
        this.options.currentValue = currentValue;
        handleValue && handleValue(currentValue);
        var diffCurrentMin = (currentValue - minValue) * divide / precision,
        startValue = currentValue - Math.floor(canvasWidth / 2 / divide) * precision;
        startValue = startValue > minValue ? startValue < maxValue ? startValue: maxValue: minValue;
        var endValue = startValue + canvasWidth / divide * precision;
        endValue = endValue < maxValue ? endValue: maxValue; // 定义原点
        var origin = {
          x: diffCurrentMin > canvasWidth / 2 ? (canvasWidth / 2 - (currentValue - startValue) * divide / precision) * 2 : (canvasWidth / 2 - diffCurrentMin) * 2,
          y: canvasHeight * 2
        }; // 定义刻度线样式
        heightDecimal = heightDecimal * 2;
        heightDigit = heightDigit * 2;
        lineWidth = lineWidth * 2; // 定义刻度字体样式
        fontSize = fontSize * 2; // 每个刻度所占位的px
        divide = divide * 2; // 定义每个刻度的精度
        var derivative = 1 / precision;

        for (var i = Math.round(startValue / precision * 10) / 10; i <= endValue / precision; i++) {
          context.beginPath(); // 画刻度线
          context.moveTo(origin.x + (i - startValue / precision) * divide, 0); // 画线到刻度高度，10的位数就加高
          context.lineTo(origin.x + (i - startValue / precision) * divide, i % 10 === 0 ? heightDecimal: heightDigit);
          context.lineWidth = lineWidth; // 10的位数就加深
          context.strokeStyle = i % 10 === 0 ? colorDecimal: colorDigit;
          context.stroke(); // 描绘刻度值
          context.fillStyle = fontColor;
          context.textAlign = 'center';
          context.textBaseline = 'top';

          if (i % 10 === 0) {
            context.font = "".concat(fontSize, "px Arial");
            context.fillText(Math.round(i / 10) / (derivative / 10), origin.x + (i - startValue / precision) * divide, heightDecimal);
          }

          context.closePath();
        }
      }
    },
    {
      key: "init",
      value: function init(options) {
        this._renderBox(options.el);
      }
    }]);
    
    return sliderRuler;
  }) ();
